package com.letv.android.client.listener;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.os.Handler;
import android.os.Message;
import android.view.Surface;
import com.letv.android.client.activity.AlbumPlayRoomActivity;
import com.letv.android.client.utils.ChangeOrientationHandler;
import java.lang.ref.WeakReference;

/**
 * 陀螺仪监听，根据重量旋转方向
 */
public class OrientationSensorListener implements SensorEventListener {

    private static final int _DATA_X = 0;
    private static final int _DATA_Y = 1;
    private static final int _DATA_Z = 2;
    private int currOrientation = -1;
    private int lastOrientation = -1;
    private int requestedOrientationGlobal = 0, orientationGlobal = 0;
    public static final int ORIENTATION_UNKNOWN = -1;
    private static final int SENSOR_CHANGED_PROCESS_TIME = 800;
    private static final int SENSOR_CHANGED_PROCESS_CONSTANT = 10001;
    private static Handler rotateHandler;

    WeakReference<Activity> mActivityReference;

    private boolean isLock;

    private int lockOnce = -1;
    private boolean isLockAll;

    private boolean justLandscape;

    private OnDirectionChangeListener onDirectionChangeListener;

    private boolean isSensorChanged = false;

    public OrientationSensorListener(Handler handler, Activity activity) {
        rotateHandler = handler;
        mActivityReference = new WeakReference<Activity>(activity);
    }

    public void onAccuracyChanged(Sensor arg0, int arg1) {
    }

    public void onSensorChanged(SensorEvent event) {
        Activity activity = mActivityReference.get();
        if (activity == null || (activity instanceof AlbumPlayRoomActivity &&
                ((AlbumPlayRoomActivity) activity).lockAll)) {
            return;
        }
        int requestedOrientation = activity.getRequestedOrientation();
        if (requestedOrientation == 4) {// 初始化为根据重力，所以在这里纠正方向
            int rt = activity.getWindowManager().getDefaultDisplay().getRotation();
            if (rt == Surface.ROTATION_0) {
                if (rotateHandler != null) {
                    rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_1)
                                 .sendToTarget();
                }
            } else if (rt == Surface.ROTATION_90) {
                if (rotateHandler != null) {
                    rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_0)
                                 .sendToTarget();
                }
            } else if (rt == Surface.ROTATION_180) {
                if (rotateHandler != null) {
                    rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_9)
                                 .sendToTarget();
                }
            } else if (rt == Surface.ROTATION_270) {
                if (rotateHandler != null) {
                    rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_8)
                                 .sendToTarget();
                }
            }
            return;
        }
        if (event.sensor == null) {
            return;
        }
        float[] values = event.values;
        int orientation = ORIENTATION_UNKNOWN;
        float X = -values[_DATA_X];
        float Y = -values[_DATA_Y];
        float Z = -values[_DATA_Z];
        float magnitude = X * X + Y * Y;
        // Don't trust the angle if the magnitude is small compared to the y
        // value
        if (magnitude * 4 >= Z * Z) {
            float OneEightyOverPi = 57.29577957855f;
            float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi;
            orientation = 90 - Math.round(angle);
            // normalize to 0 - 359 range
            while (orientation >= 360) {
                orientation -= 360;
            }
            while (orientation < 0) {
                orientation += 360;
            }
        }
        // sensorChangedProcess(requestedOrientation, orientation);
        getCurrentOrientation(orientation);
        requestedOrientationGlobal = requestedOrientation;
        orientationGlobal = orientation;
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // LogInfo.log("sensor", "--lastOriention-msg.arg1=" + msg.arg1 + " currOrientation=" + currOrientation);
            if (msg != null && msg.arg1 != currOrientation) {
                sensorChangedProcess(requestedOrientationGlobal, orientationGlobal);
            }
            isSensorChanged = false;
        }
    };

    private void getCurrentOrientation(int orientation) {
        final int lastOrientionTmp = currOrientation;
        if (orientation >= 60 && orientation <= 120) {// 反横屏
            currOrientation = ChangeOrientationHandler.ORIENTATION_8;
        } else if (orientation > 150 && orientation < 210 && !justLandscape) {// 反竖屏
            currOrientation = ChangeOrientationHandler.ORIENTATION_9;
        } else if (orientation > 240 && orientation < 300) {// 正横屏
            currOrientation = ChangeOrientationHandler.ORIENTATION_0;
        } else if ((orientation > 330 && orientation < 360)) {// 正竖屏
            currOrientation = ChangeOrientationHandler.ORIENTATION_1;
        } else if ((orientation > 0 && orientation < 30) && !justLandscape) {
            currOrientation = ChangeOrientationHandler.ORIENTATION_1;
        }
        if (lastOrientionTmp != currOrientation) {
            // LogInfo.log("sensor", "---xxxxxxxxxxxxx--lastOrientionTmp =" + lastOrientionTmp + " currOrientation=" +
            // currOrientation);
            Activity activity = mActivityReference.get();
            if (mHandler != null && activity != null && !activity.isFinishing()) {
                if (isSensorChanged) {
                    mHandler.removeMessages(SENSOR_CHANGED_PROCESS_CONSTANT);
                }
                isSensorChanged = true;
                mHandler.sendMessageDelayed(mHandler.obtainMessage(SENSOR_CHANGED_PROCESS_CONSTANT, lastOrientionTmp, 0), SENSOR_CHANGED_PROCESS_TIME);
            }
        }
    }

    /**
     * 传感器变化处理
     *
     * @param requestedOrientation
     * @param orientation
     */
    private void sensorChangedProcess(int requestedOrientation, int orientation) {
        // LogInfo.log("sensor", "lockOnce ="+lockOnce+" --requestedOrientation=" + requestedOrientation +
        // " orientation=" + orientation);
        Activity activity = mActivityReference.get();
        if (activity == null || (activity instanceof AlbumPlayRoomActivity &&
                ((AlbumPlayRoomActivity) activity).lockAll)) {
            return;
        }
        if (orientation >= 60 && orientation <= 120) {// 反横屏
            if (lockOnce == -1) {
                if (requestedOrientation != 8) {
                    if (isLock && requestedOrientation != 4) {
                        if (onDirectionChangeListener != null) {
                            onDirectionChangeListener.onChange(orientation, 8);
                        }
                        return;
                    }
                    if (rotateHandler != null) {
                        rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_8)
                                     .sendToTarget();
                    }
                }
            } else {
                if (lockOnce != 8) {
                    lockOnce = -1;
                    if (requestedOrientation != 8) {
                        if (isLock && requestedOrientation != 4) {
                            if (onDirectionChangeListener != null) {
                                onDirectionChangeListener.onChange(orientation, 8);
                            }
                            return;
                        }
                        if (rotateHandler != null) {
                            rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_8)
                                         .sendToTarget();
                        }
                    }
                }
            }
        } else if (orientation > 150 && orientation < 210 && !justLandscape) {// 反竖屏
            if (lockOnce == -1) {
                if (requestedOrientation != 9) {
                    if (isLock && requestedOrientation != 4) {
                        if (onDirectionChangeListener != null) {
                            onDirectionChangeListener.onChange(orientation, 9);
                        }
                        return;
                    }
                    if (rotateHandler != null) {
                        rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_9)
                                     .sendToTarget();
                    }
                }
            } else {
                if (lockOnce != 9) {
                    lockOnce = -1;
                    if (requestedOrientation != 9) {
                        if (isLock && requestedOrientation != 4) {
                            if (onDirectionChangeListener != null) {
                                onDirectionChangeListener.onChange(orientation, 9);
                            }
                            return;
                        }
                        if (rotateHandler != null) {
                            rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_9)
                                         .sendToTarget();
                        }
                    }
                }
            }
        } else if (orientation > 240 && orientation < 300) {// 正横屏
            if (lockOnce == -1) {
                if (requestedOrientation != 0) {
                    if (isLock && requestedOrientation != 4) {
                        if (onDirectionChangeListener != null) {
                            onDirectionChangeListener.onChange(orientation, 0);
                        }
                        return;
                    }
                    if (rotateHandler != null) {
                        rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_0)
                                     .sendToTarget();
                    }
                }
            } else {
                if (lockOnce != 0) {
                    lockOnce = -1;
                    if (requestedOrientation != 0) {
                        if (isLock && requestedOrientation != 4) {
                            if (onDirectionChangeListener != null) {
                                onDirectionChangeListener.onChange(orientation, 0);
                            }
                            return;
                        }
                        if (rotateHandler != null) {
                            rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_0)
                                         .sendToTarget();
                        }
                    }
                }
            }
        } else if (((orientation > 330 && orientation < 360) ||
                (orientation > 0 && orientation < 30)) && !justLandscape) {// 正竖屏
            if (lockOnce == -1) {
                if (requestedOrientation != 1) {
                    if (isLock && requestedOrientation != 4) {
                        if (onDirectionChangeListener != null) {
                            onDirectionChangeListener.onChange(orientation, 1);
                        }
                        return;
                    }
                    if (rotateHandler != null) {
                        rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_1)
                                     .sendToTarget();
                    }
                }
            } else {
                if (lockOnce != 1) {
                    lockOnce = -1;
                    if (requestedOrientation != 1) {
                        if (isLock && requestedOrientation != 4) {
                            if (onDirectionChangeListener != null) {
                                onDirectionChangeListener.onChange(orientation, 1);
                            }
                            return;
                        }
                        if (rotateHandler != null) {
                            rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_1)
                                         .sendToTarget();
                        }
                    }
                }
            }
        }
    }

    /**
     * 当锁屏时，切换至横屏时根据重力来设置屏幕方向
     */
    public void refreshLandspaceWhenLock() {
        if (!isLock && lockOnce == -1) {
            return;
        }

        if (orientationGlobal >= 60 && orientationGlobal <= 120) {// 反横屏
            if (rotateHandler != null) {
                rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_8).sendToTarget();
            }
        } else if (orientationGlobal > 240 && orientationGlobal < 300) {// 正横屏
            if (rotateHandler != null) {
                rotateHandler.obtainMessage(ChangeOrientationHandler.ORIENTATION_0).sendToTarget();
            }
        }
    }

    public boolean isLock() {
        return isLock;
    }

    public void setLock(boolean isLock) {
        if (!isLock && this.isLock) {
            sensorChangedProcess(requestedOrientationGlobal, orientationGlobal);
        }
        this.isLock = isLock;
    }

    public void lockOnce(int orientation) {
        this.lockOnce = orientation;
    }

    public void setLockAll(boolean lockall) {
        isLockAll = lockall;
    }

    public boolean isJustLandscape() {
        return justLandscape;
    }

    public void setJustLandscape(boolean justLandscape) {
        this.justLandscape = justLandscape;
    }

    public OnDirectionChangeListener getOnDirectionChangeListener() {
        return onDirectionChangeListener;
    }

    public void setOnDirectionChangeListener(OnDirectionChangeListener onDirectionChangeListener) {
        this.onDirectionChangeListener = onDirectionChangeListener;
    }

    public interface OnDirectionChangeListener {

        void onChange(int orientation, int orientationProperty);
    }
}
